package com.yanghui.dtracing.plugin.feign;

import com.yanghui.dtracing.core.constant.TypeEnum;
import com.yanghui.dtracing.core.opentracing.DTracer;
import com.yanghui.dtracing.core.opentracing.DTracerTags;
import com.yanghui.dtracing.core.opentracing.Tracing;
import com.yanghui.dtracing.core.plugin.interceptor.AbstractInstanceMethodInterceptor;
import com.yanghui.dtracing.core.plugin.interceptor.MethodInterceptResult;
import feign.RequestTemplate;
import feign.Target;
import io.opentracing.Span;
import io.opentracing.propagation.Format;
import io.opentracing.propagation.TextMapInject;
import io.opentracing.tag.Tags;
import lombok.AllArgsConstructor;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

public class FeignInstanceMethodInterceptor extends AbstractInstanceMethodInterceptor {

    @AllArgsConstructor
    private static class FeignHeaderCarrier implements TextMapInject {
        private RequestTemplate requestTemplate;
        @Override
        public void put(String key, String value) {
            requestTemplate.header(key, Arrays.asList(value));
        }
    }

    @Override
    protected void doBeforeMethod(Object thisObj, Method method, Object[] allArguments,
                                  MethodInterceptResult result, Span span) throws Throwable {
        RequestTemplate template = (RequestTemplate)allArguments[0];
        DTracer tracer = Tracing.getTracer();
        tracer.inject(span.context(), Format.Builtin.TEXT_MAP_INJECT,new FeignHeaderCarrier(template));

        Field targetField = thisObj.getClass().getDeclaredField("target");
        targetField.setAccessible(true);
        Target<?> target = (Target<?>)targetField.get(thisObj);

        span.setTag(DTracerTags.PEER_URL,template.url())
                .setTag(Tags.PEER_SERVICE,target.name())
                .setTag(Tags.SPAN_KIND,Tags.SPAN_KIND_CLIENT)
                .setTag(DTracerTags.TYPE, TypeEnum.EXIT.getName())
                .setTag(Tags.COMPONENT,DTracerTags.COMPONENT_FEIGN);
    }
}
